<template>
  <div class="table-container">
    <div class="pos" ref="posRef"></div>
    <el-table
      :data="tableData"
      header-cell-class-name="head-cell-cls"
      v-loading="loading"
      header-row-class-name="head-row-cls"
      :row-class-name="'row-cls'"
      row-key="id"
      :height="height"
      :max-height="maxHeight"
      :style="{ width: `100%`, minHeight: getMinHeight() }"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
      <!-- 数据为空的插槽 -->
      <template #empty>
        <el-empty :image-size="100" description="暂无数据"></el-empty>
      </template>

      <!-- 读取配置项 -->
      <template v-for="(item, index) in tableConfig">
        <!-- 如果指定了具名插槽 -->
        <el-table-column
          v-if="item.slot"
          :label="item.label"
          :prop="item.prop"
          :key="index"
          :align="item.align || 'center'"
          :fixed="item.fixed"
          :min-width="item.minWidth"
          label-class-name="col-cls">
          <template #default="scope">
            <!-- $index：表示当前行的索引，用于前端自己生成序号 -->
            <slot :name="item.slot" :data="{ ...scope.row, $no: getNo(scope.$index) }"></slot>
          </template>
          <!-- 处理表头，鼠标放上显示提示 -->
          <template #header>
            <div class="ellipsis" :title="item.label">{{ item.label }}</div>
          </template>
        </el-table-column>
        <!-- 如果指定了序号 -->
        <el-table-column
          v-else-if="item.label === '序号' || item.label === '编号'"
          :label="item.label"
          :prop="item.prop"
          :key="index + 0"
          :align="item.align || 'center'"
          label-class-name="col-cls"
          type="index"
          :index="getNo"
          :min-width="60">
          <template #header>
            <div class="ellipsis" :title="item.label">{{ item.label }}</div>
          </template>
        </el-table-column>
        <!-- 如果指定了最小宽度 -->
        <el-table-column
          v-else-if="item.minWidth"
          :label="item.label"
          :prop="item.prop"
          :key="index + 1"
          :align="item.align || 'center'"
          :min-width="item.minWidth"
          label-class-name="col-cls"
          :formatter="(row) => formatText(row, item)">
          <template #header>
            <div class="ellipsis" :title="item.label">{{ item.label }}</div>
          </template>
        </el-table-column>
        <!-- 默认显示 -->
        <el-table-column
          v-else
          :label="item.label"
          :prop="item.prop"
          :key="index + 2"
          :align="item.align || 'center'"
          label-class-name="col-cls"
          :formatter="(row) => formatText(row, item)">
          <template #header>
            <div class="ellipsis" :title="item.label">{{ item.label }}</div>
          </template>
        </el-table-column>
      </template>
    </el-table>

    <!-- <div class="uCenterX mt-15px">
			<el-pagination
				@size-change="handleSizeChange"
				@current-change="handleCurrentChange"
				:current-page.sync="pageData.pageNum"
				:page-sizes="[10, 20, 30, 40]"
				:page-size="pageData.pageSize"
				layout="total, sizes, prev, pager, next, jumper"
				:total="pageData.total">
			</el-pagination>
		</div> -->
  </div>
</template>

<script setup lang="ts">
import { nextTick, onMounted, ref, toRefs } from "vue";
import { useEventListener } from "@/hooks/useEventListener.ts";

/**
 * 强化版Table组件，兼容之前的组件
 * 支持表格自动高度`autoHeight`、设置最大高度`maxHeight`
 * 表格会自动铺满屏幕高度，可通过指定`footerHeight`来控制表格距离底部的距离
 * 所以，一般页面只要调整距离底部距离就行了
 */
defineOptions({
  name: "EnhancedTable",
});

export type IPageData = {
  /**
   * 当前页：默认应该为1
   */
  pageNum: number;
  /**
   * 总条数
   */
  total: number;
  /**
   * 每页显示条数
   */
  pageSize: number;
};

/**
 * 表单数据配置
 */
export type ITableConfig = {
  /**
   * 列名
   */
  label: string;
  /**
   * 列属性值
   */
  prop?: string;
  /**
   * 插槽名
   */
  slot?: string;
  /**
   * 列key
   */
  key?: string;
  /**
   * 列最小宽度
   */
  minWidth?: number;
  /**
   * 固定列
   */
  fixed?: string;
  /**
   * 列对齐方式
   */
  align?: "left" | "center" | "right";
};

const props = defineProps({
  /**
   * 加载中动画
   */
  loading: {
    type: Boolean,
    default: false,
  },
  /**
   * 表单数据
   */
  tableData: {
    type: Array as () => any[],
    default: () => [],
  },
  /**
   * 表单配置
   */
  tableConfig: {
    type: Array as () => ITableConfig[],
    default: () => [],
  },
  /**
   * 分页数据
   */
  pageData: {
    type: Object as () => IPageData,
    default: () => ({
      pageNum: 1,
      total: 0,
      pageSize: 20,
    }),
  },
  /**
   * 是否是自动高度
   */
  autoHeight: {
    type: Boolean,
    default: false,
  },
  /** 底部距离 */
  footerHeight: {
    type: Number,
    default: 92,
  },
  /** 最大高度 */
  maxHeight: {
    type: [Number, String],
    default: "unset",
  },
  /** 最小高度 */
  minHeight: {
    type: [Number, String],
    default: "unset",
  },
});

const { tableData } = toRefs(props);

const posRef = ref<HTMLElement | null>(null);
const height = ref<number | string>("unset");

const getMinHeight = () => {
  // console.log("Samer ~ getMinHeight ~ props.minHeight:", props.minHeight);
  if (props.minHeight !== "unset") {
    let minHeight = `${parseFloat(props.minHeight as string)}px`;
    console.log("Samer", minHeight);
    return minHeight;
  }
  return props.minHeight;
};

const formatText = (row: any, item: ITableConfig) => {
  if (item.prop) {
    return row[item.prop] == null ? "-" : row[item.prop];
  }
  return "-";
};

function updateLayout() {
  calcHeight();
}

const handleResize = () => {
  updateLayout();
};

useEventListener(window, "resize", handleResize);

onMounted(() => {
  nextTick().then(() => {
    updateLayout();
  });
});

const calcHeight = () => {
  if (!props.autoHeight) {
    // console.warn("this.autoHeight", this.autoHeight);
    let topPos = posRef.value?.getBoundingClientRect().top || 0;
    // 获取页面剩余高度
    const windowHeight = window.innerHeight || document.documentElement.clientHeight;
    let remainHeight = windowHeight - topPos - props.footerHeight;
    // console.warn("Samer Table 重新计算高度：", remainHeight);
    height.value = remainHeight + "px";
  } else {
    // console.warn("Samer", "自动高度");
    // 高度置为空，el-table会自动计算
    height.value = "";
  }
  return height.value;
};

// 获取当前序号（从1开始一直累加）
const getNo = (index: number) => {
  return (props.pageData.pageNum - 1) * props.pageData.pageSize + index + 1;
};
</script>

<style lang="scss" scoped>
::v-deep(.el-table) {
  --el-table-header-text-color: #3d3d3d;
  // 边框
  --el-table-border: none;
  --el-table-bg-color: transpace;
  --el-table-border-color: transparent;
  // 表头高度
  --table-head-height: 48px;
  --el-table-header-bg-color: #f1f9ff;

  .el-table__header-wrapper {
    // border-radius: 4px;
  }

  // 表头每个单元格样式
  .head-cell-cls {
    opacity: 1;
    background: var(--el-table-header-bg-color);
  }

  .head-row-cls {
    height: var(--table-head-height);

    // 增加圆角
    > *:first-child {
      border-top-left-radius: 4px;
      border-bottom-left-radius: 4px;
    }
    > *:last-child {
      border-top-right-radius: 4px;
      border-bottom-right-radius: 4px;
    }

    // 表头每个单元格样式
    .cell {
      height: 23px;
      opacity: 1;
      font-family: HarmonyOS Sans SC;
      font-size: 14px;
      font-weight: 500;
      line-height: 22px;
      letter-spacing: 0px;

      font-feature-settings: "kern" on;
      color: var(--el-table-header-text-color);
      // white-space: pre;
    }
  }

  // 数据项每个单元格样式
  .row-cls {
    --el-table-tr-bg-color: white;
    // border-bottom: 1px solid #e8e8e8;
    height: 48px;

    .cell {
      font-family: PingFang SC;
      font-size: 14px;
      font-weight: normal;
      line-height: 22px;
      letter-spacing: 0px;
      color: #303133;
    }
  }

  .row-cls-even {
    --el-table-tr-bg-color: #ebeef5;
  }

  .col-cls {
    // background-color: red;
  }
}

::v-deep(.el-empty) {
  // --el-text-color-secondary: white;

  // .el-empty__description {}
}
</style>
